// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// BORDERS
// =======

// ## General

border-normal($side = '', $width = 1px)
  $prefix = '-'
  if $side == ''
    $prefix = ''
  border{$prefix + $side}: $width solid var(--c-border-neutral-light)

border-dark($side = '', $width = 1px)
  $prefix = '-'
  if $side == ''
    $prefix = ''
  border{$prefix + $side}: $width solid var(--c-border-neutral-normal)

border-input($side = '', $width = 1px)
  $prefix = '-'
  if $side == ''
    $prefix = ''
  border{$prefix + $side}: $width solid var(--c-border-neutral-normal)

border-subtle($side = '', $width = 1px)
  $prefix = '-'
  if $side == ''
    $prefix = ''
  border{$prefix + $side}: $width solid var(--c-border-neutral-extralight)

gradient-border($background-color, $top-color, $bottom-color)
  background: linear-gradient(to bottom, $background-color, $background-color) padding-box, linear-gradient(to bottom, $top-color, $bottom-color) border-box

pseudo-border($size, $color)
  &:before
    position: absolute
    bottom: 0
    left: 0
    height: $size
    background: $color
    content: ''
    width: 100%
    {block}

pseudo-border-animated($size, $color)
  +pseudo-border($size, $color)
    transform: scaleX(0)
    transition: transform .2s, width .4s cubic-bezier(1, 0, 0, 1) .2s

  &:hover:before
    transform: scaleX(1)


// POSITIONING
// ======

// Nudges push the element in the specified direction by the specified amount.

nudge($direction, $amount = 1px)
  position: relative

  if $direction == 'up'
    bottom: $amount
  if $direction == 'down'
    top: $amount
  if $direction == 'left'
    right: $amount
  if $direction == 'right'
    left: $amount

// Center absolute uses absolute positioning to put the element in the
// center of its container.
center-absolute()
  top: 50%
  left: 50%
  position: absolute
  transform: translate(-50%, -50%)


// Fullscreen forces an element to be full screen using position fixed
full-screen($padding = 0)
  position: fixed
  top: $padding
  left: $padding
  right: $padding
  bottom: $padding
  width: auto
  height: auto
  transform: translate(0, 0)
  max-width: initial
  max-height: initial


// TYPOGRAPHY
// ==========

// Heading size definitions

h1()
  font-size: $fs.xxl
  line-height: $lh.xxl
  font-weight: $fwh.bold

h2()
  font-size: $fs.xl
  line-height: $lh.xl
  font-weight: $fwh.bolder

h3()
  font-size: $fs.l
  line-height: $lh.l
  font-weight: $fwh.bold

h4()
  font-size: $fs.m
  line-height: $lh.m
  font-weight: $fwh.bold

// One liner, sets line-height to 1, makes components spacing a lot easier.
// Only suitable for texts that will not wrap at all. Otherwise use
// text-spacing-* or text-margin-*

one-liner($display = inline-block)
  line-height: 1
  display: $display
  white-space: nowrap

// Text spacing will return a spacing value that compensates for the elements
// line height, in order to make it relative to the elements visual bounding
// box again. It can be used to space text elements that cannot have a
// line height of 1

text-spacing-top($val = 0rem, $line-height = @line-height)
  if not $line-height
    $line-height = $line-height-base
  $subtractor = $line-height * ($line-height-margin-factor + .04rem)
  return 'calc(%s - %s)' % ($val $subtractor)

text-spacing-bottom($val = 0rem, $line-height = @line-height)
  if not $line-height
    $line-height = $line-height-base
  $subtractor = $line-height * ($line-height-margin-factor + .04rem)
  return 'calc(%s - %s)' % ($val $subtractor)

text-spacing($up = 0rem, $down = false, $line-height = @line-height)
  text-spacing-top($up, $line-height)
  if $down
    text-spacing-bottom($down, $line-height)
  else
    text-spacing-bottom($up, $line-height)

// text-margin-top / bottom will

text-margin-top($val = 0rem, $line-height = @line-height)
  margin-top: text-spacing-top($val, $line-height)

text-margin-bottom($val = 0rem, $line-height = @line-height)
  margin-bottom: text-spacing-bottom($val, $line-height)


text-margin($up = 0rem, $down = false, $line-height = @line-height)
  text-margin-top($up, $line-height)
  if $down
    text-margin-bottom($down, $line-height)
  else
    text-margin-bottom($up, $line-height)


// Eat text margin is a shorthand mixin to strip off a text elements margins
// relative to its visual bounding box

eat-text-margins($line-height = @line-height)
  text-margin(0rem, false, $line-height)


// LAYOUT
// ======

// Horizontalize is a shorthand to make elements in a container horizonatally
// distributed.

horizontalize()
  display: flex
  justify-content: space-between

visually-hidden()
  position: absolute
  width: 1px
  height: 1px
  margin: -1px
  border: 0
  padding: 0
  white-space: nowrap
  clip-path: inset(100%)
  clip: rect(0 0 0 0)
  overflow: hidden

// SPECIAL STYLINGS
// ================

area-active()
  background-image: linear-gradient(179deg, rgba(249,249,249,.6) 0%, rgba(246,246,246,.6) 100%)
  box-shadow: inset 0 0 22px 0 rgba(0,0,0,.05)

area-hover()
  background-image: linear-gradient(179deg, rgba(249,249,249,.3) 0%, rgba(246,246,246,.3) 100%)
  box-shadow: inset 0 0 22px 0 rgba(0,0,0,.01)


// RESPONSIVENESS
// ==============

media-query($max)
  @media screen and (max-width: $max)
    {block}

media-query-min($min)
  @media screen and (min-width: $min + 1)
    {block}

media-query-between($min, $max)
  @media screen and (min-width: $min + 1) and (max-width: $max)
    {block}

media-query-height($max)
  @media screen and (max-height: $max)
    {block}

generate-responsive-classes()
  // Base definition.
  {block}
  // Responsive classes.
  for $breakpoint, $width in $bp
    +media-query($width)
      {block}

// FUNCTIONAL
// ==========

// Removes default browser focus styles and adds custom ones for the
// .focus-visible class added automatically on focused elements.
focus-visible()
  &:global(.focus-visible)
    {block}

  &:focus
    outline: 0


// FORMS
// =====

input-width-classes()
  width: 100%

  // stylelint-disable declaration-no-important
  &.input-width-3xs
    max-width: $fiw['3xs'] !important

  &.input-width-xxs
    max-width: $fiw.xxs !important

  &.input-width-xs
    max-width: $fiw.xs !important

  &.input-width-s
    max-width: $fiw.s !important

  &.input-width-m
    max-width: $fiw.m !important

  &.input-width-l
    max-width: $fiw.l !important

  &.input-width-full
    max-width: none !important
  // stylelint-enable declaration-no-important


// RESETS
// ======

reset-button()
  border: 0
  margin: 0
  padding: 0
  width: auto
  overflow: visible
  background: transparent
  color: inherit
  font: inherit
  line-height: normal
  -webkit-appearance: none
  text-align: inherit


// TRANSITIONS
// ===========

transition-color()
  transition: color $ad.xs

sidebar-transition($properties)
  transition-timing-function: cubic-bezier(.09, .515, .115, 1)
  transition-duration: 350ms
  transition-property: $properties

// Global classes attached by the sidebar component.
global-sidebar()
  :global(.with-sidebar) .main
    +media-query-min($bp.sm)
      padding-left: $sidebar-width
    +media-query-between($bp.sm, $bp.md)
      padding-left: $sidebar-width-minimized

  :global(.sidebar-minimized) .main
    +media-query-min($bp.sm)
      padding-left: $sidebar-width-minimized

  :global(.sidebar-transitioned) .main
    +media-query-min($bp.sm)
      sidebar-transition(padding-left)
